package br.com.hs.nfe.certificado;

import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERString;

/**
 * Classe responsável por obter dados do certificado.
 * @author Ranlive Hrysyk
 */
final class NomesAlternativos<T, U> {

    private T t;
    private U u;

    public NomesAlternativos() {
    }

    private NomesAlternativos(T t, U u) {
        this.t = t;
        this.u = u;
    }

    private NomesAlternativos<DERObjectIdentifier, String> recuperarNomesAlternativos(byte[] encoded)
            throws Exception {
        ASN1InputStream inputStream = new ASN1InputStream(encoded);
        DERSequence sequence = (DERSequence) inputStream.readObject();
        inputStream.close();
        Enumeration enumeration = sequence.getObjects();

        DERObjectIdentifier objectIdentifier = (DERObjectIdentifier) enumeration.nextElement();
        DERObject object = ((ASN1TaggedObject) ((ASN1TaggedObject) enumeration.nextElement()).getObject()).getObject();

        String conteudo = "";

        if (object instanceof DERString) {
            conteudo = ((DERString) object).getString();
        } else if (object instanceof DEROctetString) {
            conteudo = new String(((DEROctetString) object).getOctets(), "ISO-8859-1");
        }

        return new NomesAlternativos(objectIdentifier, conteudo);
    }

    /**
     * Recupera nomes alternativos do certificado.
     */
    public HashMap<String, String> recuperarNomesAlternativos(X509Certificate certificado) throws Exception {
        HashMap nomesAlternativos = new HashMap();

        Collection collectionSubjectAlternativeName = certificado.getSubjectAlternativeNames();
        try {
            if (collectionSubjectAlternativeName != null) {
                Iterator it = collectionSubjectAlternativeName.iterator();

                while (it.hasNext()) {
                    List subjectAlternativeName = (List) it.next();
                    switch (((Number) subjectAlternativeName.get(0)).intValue()) {
                        case 0:
                            NomesAlternativos otherName = recuperarNomesAlternativos((byte[]) (byte[]) subjectAlternativeName.get(1));
                            nomesAlternativos.put(((DERObjectIdentifier) otherName.t).getId(), otherName.u);
                            break;
                        case 1:
                            nomesAlternativos.put("Email", (String) subjectAlternativeName.get(1));
                    }
                }
            }

        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw e;
        }

        return nomesAlternativos;
    }
}
